﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Web.UI;
using System.Xml;
using Trentacular.SharePoint.SmartEditorPart.Web.UI.WebParts;

namespace Trentacular.SharePoint.SmartEditorPart.Web.UI.UserControls
{
    /// <summary>
    /// Serves as the user interface for exposing and collecting the
    /// fields for display in a <see cref="SiteMemebersWebPart" />.
    /// </summary>
    public partial class SiteMemberFieldsEditor
        : UserControl, IWebPartEditor<SiteMembersWebPart>
    {
        #region IWebPartEditor<FacetedSearchWebPart> Members

        /// <summary>
        /// Gets a reference to the
        /// <see cref="SiteMembersWebPart"/> control that is currently being edited.
        /// </summary>
        /// <returns>
        /// The <see cref="SiteMembersWebPart"/> that is currently in edit mode.
        /// </returns>
        public SiteMembersWebPart WebPartToEdit { get; set; }

        /// <summary>
        /// Saves the values of this control to the corresponding properties in the
        /// associated <see cref="SiteMembersWebPart"/> Web Part.
        /// </summary>
        /// <returns>
        /// true if the action of saving values from this control to the
        /// <see cref="SiteMembersWebPart"/> Web Part is successful; otherwise (if an
        /// error occurs), false.
        /// </returns>
        public bool ApplyChanges()
        {
            try
            {
                WebPartToEdit.Fields = GetFieldsConfiguration();
                return true;
            }
            catch (Exception e)
            {
                pnlMessages.Controls.Add(new LiteralControl(e.Message));
                pnlMessages.Visible = true;
                return false;
            }
        }

        /// <summary>
        /// Retrieves the property values from a <see cref="SiteMembersWebPart"/> Web
        /// Part for this control.
        /// </summary>
        public void SyncChanges()
        {
            txtFieldsXml.Text = GeFieldsXml();
        }

        #endregion

        private SiteMemberFieldCollection GetFieldsConfiguration()
        {
            using (var stringReader = new StringReader(txtFieldsXml.Text))
            {
                var xmlReader = XmlReader.Create(stringReader);

                var serializer = GetSerializer();

                var fieldsConfiguration = serializer.ReadObject(xmlReader)
                    as SiteMemberFieldCollection;

                if (fieldsConfiguration == null)
                    throw new ArgumentException("Invalid Fields Configuration XML");

                return fieldsConfiguration;
            }
        }

        private string GeFieldsXml()
        {
            var xmlOutput = new StringBuilder();
            var xmlWriter = XmlWriter.Create(xmlOutput, new XmlWriterSettings
            {
                Indent = true,
                OmitXmlDeclaration = true
            });

            var serializer = GetSerializer();

            serializer.WriteObject(xmlWriter, WebPartToEdit.Fields);
            xmlWriter.Flush();

            return xmlOutput.ToString();
        }

        private DataContractSerializer GetSerializer()
        {
            return new DataContractSerializer(
                typeof(SiteMemberFieldCollection)
                );
        }
    }
}